""" datastore.py

This module provides the base class for datastore-based record classes.

   Copyright 2011 Bravo369.org

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

author = Mike Meade (mmeade@google.com)
"""

# General imports
import random
import string
import time

# Frameowrk imports
from google.appengine.ext import db
from django.utils import simplejson as json


class ModelBase(db.Model):
  """The base class for a model."""
  _json_keys = []

  _type_map = {
      db.FloatProperty: float,
      db.StringProperty: str,
      db.IntegerProperty: int
      }

  @classmethod
  def className(cls):
    """Return the class name.

    Returns:
      The name of the current class.
    """
    return cls.__name__

  def toDict(self):
    """Convert the instance to a name:value dictionary.

    All values are in string format.

    Returns:
      The dictionary representation of the instance.
    """
    result = {}
    for name in self._json_keys:
      result[name] = str(getattr(self, name))
    return result

  @classmethod
  def fromDict(cls, data):
    """Create an instance from a name:value dictionary.

    Args:
      data: A dictionary to create the instance from.

    Returns:
      An instance with the correct property values.
    """
    instance = cls()
    for name, value in data.items():
      target_type = type(instance._properties[name])
      cls_type = cls._type_map[target_type]
      if cls_type in (int, float) and value is None:
        value = '0'
      setattr(instance, name, cls_type(value))
    return instance

  def toJson(self):
    """Convert the instance to a JSON representation.

    All values are in string format.

    Returns:
      The JSON representation of the instance.
    """
    data = {}
    for name in self._json_keys:
      data[name] = getattr(self, name)
    return json.dumps({self.className(): data}, indent=2)

  @classmethod
  def fromJson(cls, data):
    """Create an instance from a JSON description.

    Args:
      data: A JSON description to create the instance from.

    Returns:
      An instance with the correct property values.
    """
    data = json.loads(data)
    instance = cls()
    for name, value in data.items():
      setattr(instance, name, value)
    return instance

  @classmethod
  def deleteAll(cls):
    """Delete every instance of the class in the datastore."""
    for item in cls.all():
      item.delete()
